Back - Trigger

Software Projects - Basic JavaScript App

Lacrimae rerum. Memento mori. Memento vivere.

So Cards Carousel

So Cards are a curated set of deep conversation starters to help skip the small talk and spark a genuine connection. This project is a basic implementation to imitate the way in which So Cards are used, but it is not related to the actual creative rights of So Cards. In other words, although this idea was inspired by So Cards, it is generally applicable and intended to be relevant for any deck of cards or collection of consecutive prompts. Without any of the additional intricacies, this is essentially a simple carousel or slideshow within the selected deck or collection, where the navigation allows for transitioning forwards, backwards, to a specific input, or to a random index. The game can be quite inspirational.

How To Play

For background, So Cards are decks of cards, where each card has a prompt to answer a question: "Many people crave great conversation, but few know how to start. A good question can be the spark which ignites a forest fire of thoughts, ideas, and personal revelation. Take turns, take your time, and see where each card can take you". The cards are used by simply drawing and answering the question, although there are not strict rules and other variations or orders can be followed. The decks range from Volume 2, Volume 3, Unstuck Yourself, and More Than Friends. As mentioned, this project is not actually related to the creative rights of So Cards (examples used are publicly available from the official website).

Basic Program Design

A standard example of a simple carousel or slideshow was developed for the project. The application consists of collection buttons to select the deck, quote box to display the current prompt, and navigation button to transition through the deck. Each collection will target an independent list of quotes, while each button and input has an event listener to wait for a player to click on the button or input for navigation. When navigating within a collection, it is possible to imitate orderly scrolling through the deck of cards or picking a card indiscriminately from a random index (allows for repetition).

Design of the HTML elements used for the collection buttons, quote box, and transitioning functions:
				<div class = "buttonsGroup">
				    <button class = "button buttonCollection" id = "collectionSelect1">Volume Two</button>
				    <button class = "button buttonCollection" id = "collectionSelect2">Volume Three</button>
				    <button class = "button buttonCollection" id = "collectionSelect3">Unstuck Yourself</button>
				    <button class = "button buttonCollection" id = "collectionSelect4">More Than Friends</button>
				</div>
				<div class = "quoteBox">
				    <div id = "quoteText"></div>
				</div>
				<div class = "buttonsGroup">
				    <button class = "button buttonNavigation" id = "buttonBackward">Backward</button>
				    <input type = "number" id = "inputIndex" min = "0" value = "0">
				    <button class = "button buttonNavigation" id = "buttonForward">Forward</button>
				</div>
				<div class = "buttonsGroup">
				    <button class = "button buttonRandom" id = "buttonRandom">Random Card</button>
				</div>
Design of the JavaScript to follow the game rules using the collection buttons, quote box, and transitioning functions:
				// Function to populate the prompt with the current quote.
				function displayQuote(indexCollection, indexQuote) {
				    quoteText.textContent = collections[indexCollection][indexQuote];
				}
				
				// List of the quotes in each corresponding collection.
				const collections = [
				    [ // Volume Two
				        "What is something about your life now which you will miss when you are eighty?",
				        "What superpowers are probably more inconvenient than they are useful?",
				        "You have three days left to live with perfect health and unlimited money - what would you do?",
				    ],
				    [ // Volume Three
				        "What is a dream which you are glad that you gave up on?",
				        "If your life were a video game, who would be the final boss?",
				        "What is an underappreciated adulthood milestone?",
				    ],
				    [ // Unstuck Yourself
				        "What is something which your parents did which you never want to repeat?",
				        "What part of yourself did you lose in your last relationship?",
				        "What is an apology which you wish that you had got but never did?",
				    ],
				    [ // More Than Friends
				        "What flaws do you and I have in common?",
				        "What is an underrated way of showing affection?",
				        "If you and I had met as kids, how well would we have got along?",
				    ]
				];
				
				// Variables to track the index of the collection and quote.
				let currentIndexCollection = 0;
				let currentIndexQuote = 0;
				
				// Variables to store the values of the quote and input.
				const quoteText = document.getElementById('quoteText');
				const inputIndex = document.getElementById('inputIndex');
				
				// Display the quote with the initial indexes upon loading.
				displayQuote(currentIndexCollection, currentIndexQuote);
				
				// Event to listen for when the first collection is activated.
				document.getElementById('collectionSelect1').addEventListener('click', function() {
				    currentIndexCollection = 0;
				    currentIndexQuote = 0;
				    displayQuote(currentIndexCollection, currentIndexQuote);
				    inputIndex.value = currentIndexQuote;
				});
				
				// Event to listen for when the second collection is activated.
				document.getElementById('collectionSelect2').addEventListener('click', function() {
				    currentIndexCollection = 1;
				    currentIndexQuote = 0;
				    displayQuote(currentIndexCollection, currentIndexQuote);
				    inputIndex.value = currentIndexQuote;
				});
				
				// Event to listen for when the third collection is activated.
				document.getElementById('collectionSelect3').addEventListener('click', function() {
				    currentIndexCollection = 2;
				    currentIndexQuote = 0;
				    displayQuote(currentIndexCollection, currentIndexQuote);
				    inputIndex.value = currentIndexQuote;
				});
				
				// Event to listen for when the fourth collection is activated.
				document.getElementById('collectionSelect4').addEventListener('click', function() {
				    currentIndexCollection = 3;
				    currentIndexQuote = 0;
				    displayQuote(currentIndexCollection, currentIndexQuote);
				    inputIndex.value = currentIndexQuote;
				});
				
				// Event to listen for when the backward navigation is activated.
				document.getElementById('buttonBackward').addEventListener('click', function() {
				    currentIndexQuote = (currentIndexQuote - 1 + collections[currentIndexCollection].length) %    collections[currentIndexCollection].length;
				    displayQuote(currentIndexCollection, currentIndexQuote);
				    inputIndex.value = currentIndexQuote;
				});
				
				// Event to listen for when the forward navigation is activated.
				document.getElementById('buttonForward').addEventListener('click', function() {
				    currentIndexQuote = (currentIndexQuote + 1) % collections[currentIndexCollection].length;
				    displayQuote(currentIndexCollection, currentIndexQuote);
				    inputIndex.value = currentIndexQuote;
				});
				
				// Event to listen for when the random index is activated.
				document.getElementById('buttonRandom').addEventListener('click', function() {
				    currentIndexQuote = Math.floor(Math.random() * collections[currentIndexCollection].length);
				    displayQuote(currentIndexCollection, currentIndexQuote);
				    inputIndex.value = currentIndexQuote;
				});
				
				// Event to listen for when the input index is modified.
				inputIndex.addEventListener('change', function() {
				    let newIndex = parseInt(inputIndex.value);
				    if (newIndex >= 0 && newIndex < collections[currentIndexCollection].length) {
				        currentIndexQuote = newIndex;
				        displayQuote(currentIndexCollection, currentIndexQuote);
				    } else {
				        inputIndex.value = currentIndexQuote;
				    }
				});